package com.yjha.lzmarathonsys.utils;

import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;

/**
 * @author pluto
 */
@Service
public class FileUploadUtil {

	// 上传文件保存的路径
	@Value("${upload.windows.path}")
	private String winUploadPath;
	@Value("${upload.linux.path}")
	private String linuxUploadPath;

	// 下载文件路径
	@Value("${download.windows.path}")
	private String winDownloadPath;
	@Value("${download.linux.path}")
	private String linuxDownloadPath;

	// 模板路径
	@Value("${template.windows.path}")
	private String templateWinPath;
	@Value("${template.linux.path}")
	private String templateLinuxPath;

	@Getter
	@Value("${export-model-name}")
	private String modelName;

	// 100MB
	private static final long MAX_FILE_SIZE = 104857600;
	private static final String[] ALLOWED_EXTENSIONS_WD = {"doc", "docx", "pdf"};
	private static final String[] ALLOWED_EXTENSIONS_TP = {"jpg", "png", "jpeg"};
	private static final String[] ALLOWED_EXTENSIONS_TP_WD = {"jpg", "png", "jpeg", "doc", "docx", "pdf"};


	// 验证文件
	public String validateFile(MultipartFile file, String type) {
		if (file == null) {
			return "文件不能为空";
		}
		String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
		int dotIndex = fileName.lastIndexOf(".");
		if (dotIndex <= 0 || dotIndex >= fileName.length() - 1) {
			return "系统未知错误，请联系管理员";
		}
		String suffix = fileName.substring(dotIndex + 1).toLowerCase();
		boolean isAllowedExtensionWd = false;
		boolean isAllowedExtensionTp = false;
		boolean isAllowedExtensionTpWd = false;
		for (String ext : ALLOWED_EXTENSIONS_WD) {
			if (suffix.equals(ext)) {
				isAllowedExtensionWd = true;
				break;
			}
		}
		for (String ext : ALLOWED_EXTENSIONS_TP) {
			if (suffix.equals(ext)) {
				isAllowedExtensionTp = true;
				break;
			}
		}
		for (String ext : ALLOWED_EXTENSIONS_TP_WD) {
			if (suffix.equals(ext)) {
				isAllowedExtensionTpWd = true;
				break;
			}
		}

		switch (type) {
			case "TP":
				if (!isAllowedExtensionTp) {
					return "只支持jpg, png, jpeg的文件";
				}
				break;
			case "WD":
				if (!isAllowedExtensionWd) {
					return "只支持doc, docx, pdf的文件";
				}
			case "TP-WD":
				if (!isAllowedExtensionTpWd) {
					return "只支持jpg, png, jpeg, doc, docx, pdf的文件";
				}
				break;
		}

		if (file.getSize() <= 0) {
			return "请上传文件大小为0kb以上的文件";
		} else if (file.getSize() > MAX_FILE_SIZE) {
			return "最大支持100MB的文件";
		}
		return null;
	}

	// 有参根据系统获取文件上传地址
	public String getWinOrLinuxUploadFilePath(String fileDir) {
		return getFilePath(fileDir, winUploadPath, linuxUploadPath);
	}

	// 有参根据系统获取文件下载地址
	public String getWinOrLinuxDownloadFilePath(String fileDir) {
		return getFilePath(fileDir, winDownloadPath, linuxDownloadPath);
	}

	// 有参根据系统获取文件模板地址
	public String getWinOrLinuxTemplateFilePath(String fileDir) {
		return getFilePath(fileDir, templateWinPath, templateLinuxPath);
	}

	// 创建文件
	public void createDirectory(String uploadDir) throws IOException {
		Path path = Paths.get(uploadDir);
		if (!Files.exists(path)) {
			Files.createDirectories(path);
		}
	}

	// 获取虚拟文件名
	public String uploadFileReFalseFilePath(MultipartFile file, String uploadDir) throws IOException {
		createDirectory(uploadDir);
		String originalFilename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
		String suffix = StringUtils.getFilenameExtension(originalFilename);
		String nowDate = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
		// 真实文件地址与虚拟文件
		String falsehoodFilePath = uploadDir + nowDate + "." + suffix;
		file.transferTo(new File(falsehoodFilePath));

		return falsehoodFilePath;
	}

	// 获取真实文件名
	public String uploadFileReReallyFilePath(MultipartFile file, String uploadDir) throws IOException {
		createDirectory(uploadDir);
		String originalFilename = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
		// 真实文件地址与虚拟文件
		String reallyFilePath = uploadDir + originalFilename;
		file.transferTo(new File(reallyFilePath));
		return reallyFilePath;
	}

	// 无参根据系统获取文件上传地址，用于MyMvcConfigurer
	public String getWinOrLinuxUploadFilePath() {
		return getFilePath(winUploadPath, linuxUploadPath);
	}

	// 无参根据系统获取文件下载地址，用于MyMvcConfigurer
	public String getWinOrLinuxDownloadFilePath() {
		return getFilePath(winDownloadPath, linuxDownloadPath);
	}

	// 公有方法
	@NotNull
	private String getFilePath(String fileDir, String winPath, String linuxPath) {
		String os = System.getProperty("os.name").toLowerCase();
		if (os.contains("win")) {
			return winPath + fileDir + "\\";
		} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
			return linuxPath + fileDir + "/";
		}
		return "defaultPath";
	}

	// 公有方法
	@NotNull
	private String getFilePath(String winPath, String linuxPath) {
		String os = System.getProperty("os.name").toLowerCase();
		if (os.contains("win")) {
			return winPath;
		} else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
			return linuxPath;
		}
		return "defaultPath";
	}

}